<?php
/*
# TCE - Tight Control Environment: Hosting Platform
# Copyright (c) 2006 by the TightControl Dev Team
# http://tce.mystichost.net
#
#
# License:
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of the MPL Mozilla Public License
#    as published by the Free Software Foundation; either version 1.1
#    of the License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    MPL Mozilla Public License for more details.
#
#    You may have received a copy of the MPL Mozilla Public License
#    along with this program.
#
#    An on-line copy of the MPL Mozilla Public License can be found
#    http://www.mozilla.org/MPL/MPL-1.1.html
#
#
# The TCE Home Page is at:
#
#    http://tce.mystichost.net
*/

/* Check if the master controller has been loaded */
if (!class_exists('Controller')){
	throw new Exception('The master Controller abstraction layer has not been found!');
}

/* Define the TCE_FTP_CONTROLLERS_PATH */
define('TCE_FTP_CONTROLLERS_PATH', TCE_CONTROLLERS_PATH . 'FTP/');

/**
 * FTP_Controller class
 * 
 * Every FTP Controllers must extend on this class and replace all functions
 * Use regular returns like false, true, string, array on normal(non-fatal) behaviour
 * Otherwise, throw an exception
 */
abstract class FTP_Controller extends Controller {
	private static $Controllers = array();
	private static $ControllerInstances = array();
	/**
     * Creates a new FTP user with the given $Homedir
     *
     * @param string $Username
     * @param string $Password
     * @param string $Homedir
     * @param integer $UID
     * @param integer $GID
     * @param boolean $Enabled
     */
	abstract function createUser($Username, $Password, $Homedir, $UID = 0, $GID = 0, $Enabled = true);
	/**
     * Delete the given user
     *
     * @param string $Username
     * @param boolean $KeepFiles
     * @return boolean
     */
	abstract function deleteUser($Username, $KeepFiles = true);
	/**
	 * Disable the given user
	 *
	 * @param string $Username
    * @return boolean
	 */
	abstract function disableUser($Username);
	/**
	 * Enable the given user
	 *
	 * @param string $Username
    * @return boolean
	 */
	abstract function enableUser($Username);
	/**
     * Return a list of FTP users
     *
     * @param integer $From
     * @param integer $Limit
     * @return boolean
     */
	abstract function listUsers($From = 0, $Limit = 0);
	/**
     * Sets the hd quota of a certain user
     * When $SoftLimit is > $HardLimit then $HardLimit will be set equal with $HardLimit
     * 
     * @param string $Username
     * @param integer $SoftLimit
     * @param integer $HardLimit
     * @return boolean
     */
	abstract function setQuota($Username, $SoftLimit = 0, $HardLimit = 0);
	/**
     * Gets the soft limit for a FTP user
     *
     * @param string $Username
     * @return integer
     */
	abstract function getSoftLimit($Username);
	/**
     * Gets the hard limit for a FTP user
     *
     * @param string $Username
     * @return integer
     */
	abstract function getHardLimit($Username);
	/**
     * Returns information about the ftp server
     * Every class should return array('Version' => 'unknown', 'Online' => 'unknown', 'Product' => 'ProFTPd')
     * 
     * @return array
     */
	abstract function getServerStatus();
	/**
	 * Returns a list of connections
	 *
	 * @param string $Username if not empty, only the connections for this user will be returned
	 * @return array of array ('id' => '', 'command' => '', 'time' => 0)
	 */
	abstract function listConnections($Username = '');
	/**
	 * Kills a FTP session by its connection_id (returned from listConnections)
	 *
	 * @param integer $ConnectionID
	 * @param string $Username if this empty no checking on the owner of the process will be done
	 * @return boolean
	 */
	abstract function killConnection($ConnectionID, $Username = '');
	/**
	 * Kills all connections
	 * 
	 * @param string $Username if this is not empty, only the ftp connections for the given user will be killed
	 *
	 */
	abstract function killAllConnections($Username = '');
	/**
	 * Return true if the controller can list current ftp connections
	 *
	 * @return boolean
	 */
	abstract function canListConnections();
	/**
	 * Return true if the controller can kill a ftp connections
	 *
	 * @return boolean
	 */
	abstract function canKillConnections();
	/**
	 * Return true if the controller can handle quotas
	 *
	 * @return boolean
	 */
	abstract function canHandleQuota();
	/**
	 * Return true if the controller can disable/enable ftp accounts
	 *
	 * @return boolean
	 */
	abstract function canDisable();
	/**
	 * Returns an array of the information that is needed to handle the ftp server (db_name and so on)
	 * 
	 * Example result:
	 * 
	 * $Array[0] = array('Field' => 'SERVER', 'Name' => 'Server', 'Description' => 'The FTP server to connect to', 'Required' => false, 'Default' => '')
	 * 
	 * @return array
	 */
	abstract function getConfigFields();
	/**
	 * Sets the configuration
	 * 
	 * To know what kind of configuration options there are, check getConfigFields()
	 *
	 * @param array $Configuration
	 * @return boolean
	 */
	abstract function setConfigFields($Configuration = false);
	/**
	 * Ask to start interfacing with the FTP server using the configuration 
	 * set by setConfigFields  OR by supplying $Configuration
	 *
	 * @param variable $Configuration
	 * @return boolean
	 */
	abstract function startInterface($Configuration = false);
	/**
	 * Stop interfacing with the FTP server
	 * 
	 * Should be called in a __destruct() function 
	 * 
	 * @return boolean
	 */
	abstract function endInterface();
	/**
	 * Should return an array like this return array('Name' => 'FTP Controller', 'Description' => 'A FTP Controller');
	 *
	 * @return array
	 */
	abstract function getControllerInfo();
	/**
	 * Ths function loads all relevant controllers
	 *
	 * @return boolean
	 */
	static function loadControllers(){
		$Folder = TCE_FTP_CONTROLLERS_PATH;
		$Files = array();
		if (is_dir($Folder)) {
			if ($dh = opendir($Folder)) {
				while (($file = readdir($dh)) !== false) {
					if (!is_dir($Folder . $file)){
						if (substr($file, -15) == '.controller.php'){
							$Files[] = $Folder . $file;
						}
					}
				}
				closedir($dh);
			}
			$Cnt = count($Files);
			for ($i=0;$i<$Cnt;$i++){
				include_once $Files[$i];
			}
			return true;
		}else{
			return false;
		}
	}
	/**
	 * Returns the list of support controllers
	 *
	 * @return array
	 */
	static function listControllers (){
		return FTP_Controller::$Controllers;
	}
	/**
	 * Register Controller class $ControllerClass
	 *
	 * @param string $Controller
	 */
	static function Register($Controller){
		FTP_Controller::$Controllers[] = $Controller; // TODO Check if it isn't already added? (sinnerg, 13/10/2006)
	}
	/**
	 * Creates a new instance of $ControllerClass if $Persistent is set to false
	 *
	 * @param string $ControllerClass
	 * @param boolean $Persistent
	 * @param string $PersistentID
	 * @return boolean/object
	 */
	static function &createController($ControllerClass, $Persistent = false, $PersistentID = 'default'){
		/* If persistent and the object already exists, return a reference to it */
		if (($Persistent) && (isset(self::$ControllerInstances['[' . $PersistentID . '] ' . strtolower($ControllerClass)]))){
			return self::$ControllerInstances['[' . $PersistentID . '] ' . strtolower($ControllerClass)];
		}

		$Classes = self::listControllers();
		$Cnt = count($Classes);
		for ($i=0;$i<$Cnt;$i++){
			if (strtolower($ControllerClass) == strtolower($Classes[$i])){
				$Obj =& new $ControllerClass();
				if ($Persistent){
					self::$ControllerInstances['[' . $PersistentID . '] ' . strtolower($ControllerClass)] =& $Obj;
				}
				return $Obj;
			}
		}
		/* No class found, return false (are you sure that loadControllers got called?) */
		return false;
	}
}

?>